原文題目
Given a string s, find the length of the longest substring without repeating characters.
題目摘要
Example 1:
Input: s = "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.
Example 2:
Input: s = "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.
Example 3:
Input: s = "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3.
Notice that the answer must be a substring, "pwke" is a subsequence and not a substring.
解題思路
left 和 right 分別控制滑動窗口的左右邊界,right 用來遍歷字串,left 用來調整窗口大小以保證窗口內不包含重複字符。Set<Character> 來儲存當前窗口中的字符,這個集合用來快速檢查當前窗口內是否有重複字符。right 進行遍歷,每次將 right 指向的字符加入到 Set 中。Set 中已經存在 right 指向的字符,說明當前窗口內有重複字符。left 指標來縮小窗口,並且移除 left 指向的字符,直到窗口內不再包含重複字符。right - left + 1),並更新 maxLength,保留最大值。right 遍歷到字串末尾後,返回 maxLength 作為最長的不重複子字串的長度。程式碼
class Solution {
public int lengthOfLongestSubstring(String s) {
Set<Character> charSet = new HashSet<>(); //用來儲存當前不重複的字符集合
int maxLength = 0; //紀錄最長的不重複子字串長度
int left = 0; //設立左指標來控制滑動窗口的左邊界
//右指標遍歷整個字串
for (int right = 0; right < s.length(); right++) {
//當字符集合中包含當前右指標指向的字符時
while (charSet.contains(s.charAt(right))) {
charSet.remove(s.charAt(left)); //移除左指標指向的字符
left++; //左指標右移,縮小窗口
}
charSet.add(s.charAt(right)); //將當前右指標指向的字符加入集合
maxLength = Math.max(maxLength, right - left + 1); //更新最長子字串的長度
}
return maxLength; //回傳最長的不重複子字串長度
}
}
結論
這道題目是用滑動視窗來解決,在解題過程中,滑動窗口的左右指標可以有效地幫助我們動態地調整範圍,確保窗口內的字元不重複。同時透過 Set 來快速檢查重複字元,讓我們能夠在遇到重複字元時,及時調整左指標 來縮小窗口,並不斷更新最長子字串的長度。透過這次練習,能更好地理解如何在大數據或長字串的情況下,利用滑動窗口技術來解決重複元素檢查的問題。